package com.spring.io;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class ResourceResolver {

    private String basePackage;

    public ResourceResolver(String basePackage) {
        this.basePackage = basePackage;
    }


    /**
     * 扫描
     * @return 类的全路径列表
     */
    public List<String> scan(){
        this.basePackage = this.replaceDtoToSlash(this.basePackage);

        return scanClassFile(this.basePackage);
    }

    /**
     * 扫描指定路径下的class文件
     * @param basePackage 指定的路径
     * @return 指定路径下class的全路径列表
     */
    private List<String> scanClassFile(String basePackage) {
        URL url = this.getContextLoader().getResource(basePackage);
        if (url == null) {
            throw new RuntimeException("包扫描路径不正确");
        }

        String absPath = url.getFile();
        File file = new File(absPath);

        ArrayList<String> collect = new ArrayList<>();
        this.loopForScan(file, collect);

        return collect.stream().map(this::getClassFullPath).map(this::replaceSlashToDot).collect(Collectors.toList());
    }


    /**
     * 扫描指定路径下的class文件，返回class的全路径
     * @param file：指定路径
     * @param collect：存储结果的容器
     */
    private void loopForScan(File file, List<String> collect) {
        if (file.isFile()) {
            collect.add(file.getAbsolutePath());
        }
        if (file.isDirectory()) {
            for (File subFile : Objects.requireNonNull(file.listFiles())) {
                if (subFile.isDirectory()) {
                    this.loopForScan(subFile, collect);
                    continue;
                }
                collect.add(subFile.getAbsolutePath());
            }
        }
    }


    /**
     * 获取 classLoader
     * @return 从当前线程中获取classLoader，获取不到从当前类中获取
     */
    private ClassLoader getContextLoader() {

        ClassLoader loader = null;

        loader = Thread.currentThread().getContextClassLoader();

        if (loader == null) {
            loader = getClass().getClassLoader();
        }

        return loader;
    }


    /**
     * 从绝对路径中提取类的全路径
     * @param adsPath 绝对路径
     * @return 类的全路径
     */
    private String getClassFullPath(String adsPath){
        if ("".equals(adsPath)) {
            return adsPath;
        }
        if (!adsPath.contains("com") && !adsPath.contains(".class")){
            throw new RuntimeException("传入的字符串不符合提取条件");
        }
        return adsPath.substring(adsPath.indexOf("com"), adsPath.indexOf(".class"));
    }


    /**
     * 替换字符串中的斜杠
     * @param str "com/ali"
     * @return "com.ali"
     */
    private String replaceSlashToDot(String str) {
        if ("".equals(str)) {
            return str;
        }
        return str.replace("/", ".");
    }


    /**
     * 替换字符串中的点
     * @param str "com.ali"
     * @return "com/ali"
     */
    private String replaceDtoToSlash(String str) {
        if ("".equals(str)) {
            return str;
        }
        return str.replace(".", "/");
    }

}
